#ifndef EXPR_CONTROLLER_H
#define EXPR_CONTROLLER_H

#include <iostream>
#include <vector>
#include "Runner\Runner.h"
#include "Evaluate\Evaluate.h"
#include "CoverageTable.h"

using namespace std;



class ExprController
{
public:
	ExprController(string const& configFile);


public:
	/// Run the experiment and store the empirical results.
	int Run();

private:
	/// <RunOnce> is called by <Run>, which execute evolution once.
	int RunOnce(int index);

protected:

	/// Get the ostream of the output
	ostream& Out() { return *pOut_; }	

protected:
	
	/// Update the coverage table
	void UpdateCovTable(int index);
	/// Let all statisits to generate summaries and store 
	/// them into the output.
	void Summary(int index);


private:
	/// Initialize the basic experiment settings.
	void InitializeExperiment();

	void InitialTotalComb();

	void InitializePop(int index);

	bool alreadyExist(int index);

	bool Terminate(int paraIndex);

	int RemainComb(int paraIndex);

	/// Set log sink
	/// \param outStr "false": no log; "console": log to console; "filename": log to file with "filename"
	void InitializeLog(std::string const& logStr);

	/// Set out sink
	/// \param outStr "false": no output; "console": output to console; "filename": output to file with "filename"
	void InitializeOut(std::string const& outStr);
	

private:		
	/// input file
	string configFile;
	/// output file
	string outFile;
	/// config combination parameter from file
	vector<vector<int>> para;
	/// repeat num of every experiment
	vector<int> repNum;
	/// algorithm configuration
	vector<vector<double>> algPara;
	/// total number of combinations
	vector<int> totalComb;
	/// test suite
	vector<vector<int>> suite;
	/// population for ga or pso
	vector<vector<int>> population;
	/// algorithm
	vector<int> alg;    //0: GA; 1: PSO
	/// runner of GA or PSO
	Runner *runner;
	/// Coverage Table
	CoverageTable *ct;
	/// output file of Noah
	ofstream outFile_;		
	/// output stream of Noah
	ostream* pOut_;	

private:
	//result
	vector<vector<int>> suiteSize;
	vector<vector<int>> consumeTime;

};	//class ExprController


#endif